package com.lgj.auth.config;

import com.lgj.auth.code.customize.weChat.WeChatAuthenticationProvider;
import com.lgj.auth.code.handler.exception.AuthClientExceptionHandler;
import com.lgj.auth.code.service.CustomerUserDetailService;
import com.lgj.auth.code.customize.mobile.SmsVerificationCodeAuthenticationProvider;
import com.lgj.auth.jdbc.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.pqc.crypto.newhope.NHSecretKeyProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author: guangjie.liao
 * @Date: 2022/11/18 09:58
 * @Description: springSecurity 配置
 */
@Slf4j
@Order(2)
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //必须配置，不然OAuth2的http配置不生效
                .requestMatchers()
                .antMatchers("/auth/**","/oauth/**")
                .and()
                .authorizeRequests()
                // 自定义页面或处理url是，如果不配置全局允许，浏览器会提示服务器将页面转发多次
                .antMatchers("/auth/login", "/auth/authorize")
                .permitAll()
                .anyRequest()
                .authenticated();

        // 表单登录
        http.formLogin()
                // 登录页面
                .loginPage("/auth/login")
                // 登录处理url
                .loginProcessingUrl("/auth/authorize");
        http.httpBasic().disable();

    }


    /**
     *
     * @param auth the {@link AuthenticationManagerBuilder} to use
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder);
        auth.authenticationProvider(smsVerificationCodeAuthenticationProvider());
        auth.authenticationProvider(weChatAuthenticationProvider());
    }


    /**
     * AuthenticationManager 中的authenticate 是真正的授权认证地方，
     * 会调用对应的AuthenticationProvider 类的authenticate方法认证
     * @throws Exception
     */
    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 查询用户信息
     * @return
     */
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return new CustomerUserDetailService(userRepository);
    }

    /**
     * 自定义手机验证码登录
     * @return
     */
    @Bean
    public SmsVerificationCodeAuthenticationProvider smsVerificationCodeAuthenticationProvider(){
        return new SmsVerificationCodeAuthenticationProvider(userDetailsService());
    }

    @Bean
    public WeChatAuthenticationProvider weChatAuthenticationProvider(){
        return new WeChatAuthenticationProvider(userDetailsService());
    }
}
